package com.du.spring5.proxy;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.util.Arrays;

/**
 * @author : DuJiabao
 * @Project : spring
 * @Time : 2021/4/10 15:21
 * @Desc :
 */
@Component
@Aspect
@Order(1)
public class CalculatorProxy {

  @Pointcut("execution(* com.du.spring5.bean.*.*(..))")
  public void pointcut() {
  }

  @Before(value = "pointcut()")
  public void before(JoinPoint joinPoint) {
    // 获取方法的所有输入参数
    Object[] args = joinPoint.getArgs();
    // 获取签名
    Signature signature = joinPoint.getSignature();
    System.out.println("【普通Before】正在执行[" + signature.getName() + "]方法, 参数为" + Arrays.toString(args));
  }

  @AfterReturning(value = "pointcut()", returning = "result")
  public void afterReturning(Object result) {
    System.out.println("【普通AfterReturning】方法执行结束，返回值为" + result);
  }

  @After(value="pointcut()")
  public void after() {
    System.out.println("【普通After】方法执行结束");
  }

  @AfterThrowing(value = "pointcut()", throwing = "exception")
  public void afterThrowing(Exception exception) {
    System.out.println("【普通AfterThrowing】发生了" + exception + "异常");
  }

  @Around(value="pointcut()")
  public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
    try {
      System.out.println("【环绕前置通知】");
      Object[] args = joinPoint.getArgs();
      Object res = joinPoint.proceed(args);
      System.out.println("【环绕返回通知】,结果为" + res);
      return res;
    } catch (Throwable throwable) {
      System.out.println("【环绕异常通知】");
      throw new RuntimeException(throwable);
    } finally {
      System.out.println("【环绕后置通知】");
    }
  }
}
